This specification relates to compiler optimizations, and particularly to determination of function side effects of program functions.
A software tool, called a “compiler,” can translate a computer program written in a high-level programming language into a set of low-level machine instructions that can be executed by a computer's microprocessor. In the context of this translation, the program written in the high-level programming language is called the “source code.” The set of low-level machine instructions are called “object code.” In practice, a program typically includes multiple source code files from which a number of object files can be derived. In addition, the source code files may make references or calls to subroutines included in one or more software libraries. These multiple object files and libraries can be linked (i.e., combined) by a “linker” to create a single executable program.
As modern computer programs grow larger and more complex, the sequencing and placement of machine instructions in an executable program can greatly affect the efficiency and speed of the program's execution. Modern compilers can often perform various optimizations during program compilation to produce better performing object code, and consequently, more efficient executable programs. Common optimization techniques include loop optimization, data flow optimization, dead code elimination, inline expansion, constant propagation, and so on. The scope of code optimization can be intra-procedural (i.e., within a single procedure or code block) or inter-procedural (i.e., across multiple procedures or even multiple source code files).
The extent to which various optimization techniques can be applied during the compilation and linking of a computer program can be limited by the side effects that each function or expression can introduce to their respective program contexts in the original program code. Side effects of a program function include modifications to program state or interactions with surrounding expressions and the calling functions by the program function, for example. A compiler typically forgoes particular optimizations on a code block or procedure if the pertinent function side effects of the program functions contained in the code block or procedure cannot be reliably ascertained.